package com.pixelutilitys.arcade.emulators.AEPgb;
/*
JavaBoy
COPYRIGHT (C) 2001 Neil Millstone and The Victoria University of Manchester
;;;
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
*/
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
/** This is the central controlling class for the sound.
* It interfaces with the Java Sound API, and handles the
* classes for each sound channel.
*/
class SoundChip {
/** The DataLine for outputting the sound */
SourceDataLine soundLine;
SquareWaveGenerator channel1;
SquareWaveGenerator channel2;
VoluntaryWaveGenerator channel3;
NoiseGenerator channel4;
boolean soundEnabled = false;
/** If true, channel is enabled */
boolean channel1Enable = true,
channel2Enable = true,
channel3Enable = true,
channel4Enable = true;
/** Current sampling rate that sound is output at */
int sampleRate = 44100;
/** Amount of sound data to buffer before playback */
int bufferLengthMsec = 200;
/** Initialize sound emulation, and allocate sound hardware */
public SoundChip() {
soundLine = initSoundHardware();
channel1 = new SquareWaveGenerator(sampleRate);
channel2 = new SquareWaveGenerator(sampleRate);
channel3 = new VoluntaryWaveGenerator(sampleRate);
channel4 = new NoiseGenerator(sampleRate);
}
/** Initialize sound hardware if available */
public SourceDataLine initSoundHardware() {
try {
AudioFormat format =
new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
sampleRate,
8,
2,
2,
sampleRate,
true);
DataLine.Info lineInfo =
new DataLine.Info(SourceDataLine.class, format);
if (!AudioSystem.isLineSupported(lineInfo)) {
System.out.println("Error: Can't find audio output system!");
soundEnabled = false;
} else {
SourceDataLine line =
(SourceDataLine) AudioSystem.getLine(lineInfo);
int bufferLength = (sampleRate / 1000) * bufferLengthMsec;
line.open(format, bufferLength);
line.start();
// System.out.println("Initialized audio successfully.");
soundEnabled = true;
return line;
}
} catch (Exception e) {
System.out.println("Error: Audio system busy!");
soundEnabled = false;
}
return null;
}
/** Change the sample rate of the playback */
public void setSampleRate(int sr) {
sampleRate = sr;
soundLine.flush();
soundLine.close();
soundLine = initSoundHardware();
channel1.setSampleRate(sr);
channel2.setSampleRate(sr);
channel3.setSampleRate(sr);
channel4.setSampleRate(sr);
}
/** Change the sound buffer length */
public void setBufferLength(int time) {
bufferLengthMsec = time;
soundLine.flush();
soundLine.close();
soundLine = initSoundHardware();
}
/** Adds a single frame of sound data to the buffer */
public void outputSound() {
if (soundEnabled) {
int numSamples;
if (sampleRate / 28 >= soundLine.available() * 2) {
numSamples = soundLine.available() * 2;
} else {
numSamples = (sampleRate / 28) & 0xFFFE;
}
byte[] b = new byte[numSamples];
if (channel1Enable)
channel1.play(b, numSamples / 2, 0);
if (channel2Enable)
channel2.play(b, numSamples / 2, 0);
if (channel3Enable)
channel3.play(b, numSamples / 2, 0);
if (channel4Enable)
channel4.play(b, numSamples / 2, 0);
soundLine.write(b, 0, numSamples);
}
}
}